﻿#include "DevUpForm.h"
#include "ui_DevUpForm.h"

#include <QFileDialog>
#include <QCryptographicHash>
#include <QMessageBox>
#include <QTextCodec>
#include <QFileDialog>
#include <QDebug>
#include <QProcess>

#include <sapi.h>
#include <sphelper.h>
#include "singleton.h"
#include "myapp.h"

#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "sapi.lib")

DevUpForm::DevUpForm(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::DevUpForm)
{
    ui->setupUi(this);

    this->init();
}

DevUpForm::~DevUpForm()
{
    delete ui;
}

void DevUpForm::on_pushButton_proChoose_clicked()
{
    QString currPath = QDir::currentPath();
    QString filename = QFileDialog::getOpenFileName(this, tr("open pro name"), currPath, tr("pro name") + "(*.*);;");

    if(filename.isEmpty())
    {
        return;
    }

    ui->lineEdit_proname->setText(filename);
}

void DevUpForm::on_pushButton_proUp_clicked()
{
    QString filename = ui->lineEdit_proname->text();
    QString md5 = this->getMd5(filename);
    if(md5.isEmpty())
    {
        QMessageBox::warning(this, tr("info"), tr("no file"), QMessageBox::Ok, QMessageBox::NoButton);
        return;
    }

    // 取文件名
    int index = filename.lastIndexOf("/");
    QString fn = filename.mid(index + 1);
    QJsonObject body;
    body.insert("filename", fn);
    body.insert("md5", md5);

    Singleton::Instance()->onSendParam("Upgrade", body);

    // websocket 发送二进制文件
    QFile file(filename);
    if(!file.exists())
    {
        return;
    }
    if(!file.open(QIODevice::ReadOnly))
    {
        return;
    }

    QByteArray fileArr = file.readAll();
    WsBinHeader header;
    memset(&header, 0, sizeof (header));
    if(filename.startsWith("audio"))
    {
        header.tag = 4;
    }
    else
    {
        header.tag = 2;
    }
    header.totalSize = fileArr.size();
    QByteArray SendArr;
    SendArr.append((char *)&header, sizeof(header));
    SendArr.append(fileArr);
    Singleton::Instance()->sendBinaryMessage(SendArr);
}
void DevUpForm::onAppUpgrade(QJsonObject body)
{
    if(body.value("step").toInt() == 2)
    {
        if(!body.value("md5").toInt())
        {
            if(QMessageBox::warning(this, tr("警告"), tr("md5校验错误"), QMessageBox::Ok, QMessageBox::NoButton))
            {
                return;
            }
        }
    }
    ui->progressBar->setValue(body.value("pct").toInt());
    if(body.value("pct").toInt() == 100)
    {
        if(QMessageBox::information(this, tr("通知"), tr("升级成功"), QMessageBox::Ok, QMessageBox::NoButton))
        {
            ui->progressBar->setValue(0);
            return;
        }
    }
}

QString DevUpForm::getMd5(const QString &filename) const
{
    QFile file(filename);

    if(!file.exists())
    {
        return "";
    }

    QString md5;
    QByteArray md5Arr = QCryptographicHash::hash(filename.toLatin1(), QCryptographicHash::Md5);
    md5.append(md5Arr.toHex());

    return md5;
}

void DevUpForm::init()
{
}

void DevUpForm::on_pushButton_start_clicked()
{
    if(ui->plainTextEdit->toPlainText().isEmpty())
    {
        if(QMessageBox::warning(this, "警告", "试听内容为空", QMessageBox::Ok, QMessageBox::NoButton))
        {
            return;
        }
    }
    ISpVoice *voice = NULL;

// com 初始化
    if(FAILED(::CoInitialize(NULL)))
    {
        return;
    }

    // 获取 ISpVoice 接口
    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&voice);

    if(SUCCEEDED(hr))
    {

        QString qinfo = QString("%1").arg(ui->plainTextEdit->toPlainText());
        std::wstring wstrInfo = qinfo.toStdWString();
        LPCWSTR lpcwstr = wstrInfo.c_str();
        voice->SetRate(ui->horizontalSlider_rate->value());
        voice->SetVolume(ui->horizontalSlider_volume->value());
        hr = voice->Speak(lpcwstr, 0, NULL);
        voice->Release();
        voice = NULL;
    }

    ::CoUninitialize();
}

void DevUpForm::on_pushButton_export_clicked()
{

    if(ui->plainTextEdit->toPlainText().isEmpty())
    {
        if(QMessageBox::warning(this, "警告", "导出内容为空", QMessageBox::Ok, QMessageBox::NoButton))
        {
            return;
        }
    }
    //QString saveFile = QFileDialog::getSaveFileName(this, tr("save a pcm"), QDir::currentPath(), "pcm(*.pcm);;");

    bool fileExist = false;
    ISpVoice *voice = NULL;

    // com 初始化
    if(FAILED(::CoInitialize(NULL)))
    {
        return;
    }

    // 获取 ISpVoice 接口
    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&voice);

    if(SUCCEEDED(hr))
    {
        CComPtr<ISpStream> cpWavStream;
        CComPtr<ISpStreamFormat> cpOldStream;
        CSpStreamFormat originalFmt;
        voice->GetOutputStream(&cpOldStream);
        originalFmt.AssignFormat(cpOldStream);

        QString file = QCoreApplication::applicationDirPath() + "/output.wav";
        QString qfile = QString("%1").arg(file);
        std::wstring wstrFile = qfile.toStdWString();
        LPCWSTR lpcwstrFile = wstrFile.c_str();
        hr = SPBindToFile(lpcwstrFile, SPFM_CREATE_ALWAYS, &cpWavStream, &originalFmt.FormatId(), originalFmt.WaveFormatExPtr());
        voice->SetOutput(cpWavStream, TRUE);

        if(SUCCEEDED(hr))
        {
            QString qinfo = QString("%1").arg(ui->plainTextEdit->toPlainText());
            std::wstring wstrInfo = qinfo.toStdWString();
            LPCWSTR lpcwstr = wstrInfo.c_str();
            voice->SetRate(ui->horizontalSlider_rate->value());
            voice->SetVolume(ui->horizontalSlider_volume->value());
            hr = voice->Speak(lpcwstr, 0, NULL);
            voice->Release();
            voice = NULL;

            fileExist = true;
        }
    }

    ::CoUninitialize();

    if(fileExist)
    {
//        QString wavFile = QCoreApplication::applicationDirPath() + "/output.wav";
//        QString ffmpegCmd = QCoreApplication::applicationDirPath() + "/ffmpeg/ffmpeg";

//        QProcess process;
//        ffmpegCmd = ffmpegCmd + " -i " + wavFile + " -f s16le -ar 16000 -ac 1 -acodec pcm_s16le " + saveFile;
//        int ret = process.execute(ffmpegCmd);
//        process.close();
        int ret = 0;
        QMessageBox::question(this, tr("info"), (ret == 0) ? tr("exportSuccess") : tr("exportFailed"), QMessageBox::Yes);
    }
}

void DevUpForm::on_pushButton_upload_clicked()
{

    if(ui->plainTextEdit->toPlainText().isEmpty())
    {
        if(QMessageBox::warning(this, "警告", "上传语音为空", QMessageBox::Ok, QMessageBox::NoButton))
        {
            return;
        }
    }
    QString saveFile = QCoreApplication::applicationDirPath() + "/audio_out.pcm";

    bool fileExist = false;
    ISpVoice *voice = NULL;

    // com 初始化
    if(FAILED(::CoInitialize(NULL)))
    {
        return;
    }

    // 获取 ISpVoice 接口
    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&voice);

    if(SUCCEEDED(hr))
    {
        CComPtr<ISpStream> cpWavStream;
        CComPtr<ISpStreamFormat> cpOldStream;
        CSpStreamFormat originalFmt;
        voice->GetOutputStream(&cpOldStream);
        originalFmt.AssignFormat(cpOldStream);

        QString file = QCoreApplication::applicationDirPath() + "/output.wav";
        QString qfile = QString("%1").arg(file);
        std::wstring wstrFile = qfile.toStdWString();
        LPCWSTR lpcwstrFile = wstrFile.c_str();
        hr = SPBindToFile(lpcwstrFile, SPFM_CREATE_ALWAYS, &cpWavStream, &originalFmt.FormatId(), originalFmt.WaveFormatExPtr());
        voice->SetOutput(cpWavStream, TRUE);

        if(SUCCEEDED(hr))
        {
            QString qinfo = QString("%1").arg(ui->plainTextEdit->toPlainText());
            std::wstring wstrInfo = qinfo.toStdWString();
            LPCWSTR lpcwstr = wstrInfo.c_str();
            voice->SetRate(ui->horizontalSlider_rate->value());
            voice->SetVolume(ui->horizontalSlider_volume->value());
            hr = voice->Speak(lpcwstr, 0, NULL);
            voice->Release();
            voice = NULL;

            fileExist = true;
        }
    }

    ::CoUninitialize();

    if(fileExist)
    {
        // QString wavFile = QCoreApplication::applicationDirPath() + "/output.wav";
        // QString ffmpegCmd = QCoreApplication::applicationDirPath() + "/ffmpeg/ffmpeg";

        // QProcess process;
        // ffmpegCmd = ffmpegCmd + " -i " + wavFile + " -f s16le -ar 16000 -ac 1 -acodec pcm_s16le " + saveFile;
        // int ret = process.execute(ffmpegCmd);
        // process.close();
        // if(!ret)
        // {
        QMessageBox::question(this, tr("info"),  tr("导出成功"), QMessageBox::Yes);
        return;
        // }
    }

    //上传
    QString filename = saveFile;
    QString md5 = this->getMd5(filename);
    if(md5.isEmpty())
    {
        QMessageBox::warning(this, tr("info"), tr("no file"), QMessageBox::Ok, QMessageBox::NoButton);
        return;
    }

    // 取文件名
    int index = filename.lastIndexOf("/");
    QString fn = filename.mid(index + 1);
    QJsonObject body;
    body.insert("devId", myApp::current_devId);
    body.insert("filename", fn);
    body.insert("md5", md5);

    Singleton::Instance()->onSendParam("Upgrade", body);

    // websocket 发送二进制文件
    QFile file(filename);
    if(!file.exists())
    {
        return;
    }
    if(!file.open(QIODevice::ReadOnly))
    {
        return;
    }

    QByteArray fileArr = file.readAll();
    WsBinHeader header;
    memset(&header, 0, sizeof (header));
    header.tag = 4;
    header.totalSize = fileArr.size();
    QByteArray SendArr;
    SendArr.append((char *)&header, sizeof(header));
    SendArr.append(fileArr);
    Singleton::Instance()->sendBinaryMessage(SendArr);
    QMessageBox::information(this, tr("通知"), tr("发送成功"), QMessageBox::Yes);

}
